package org.dbp.bd.jpa;

import java.math.BigDecimal;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * Se encarga de trabajar cona las difernetes secuencias, para JPA.
 * 
 * Nota: La utilidad es para poder obetener el identificador, antes de la insercion. Por ejemplo en los casos de los grid
 * es interesante obetener ul ID antes de usarlo u otras utilidades.
 * 
 * TODO: Falta por crear los test. 
 * 
 * @author David Blanco París
 *
 */
public class SecuenciasJpaDbpUtils {

	private static Logger logger = LoggerFactory.getLogger(SecuenciasJpaDbpUtils.class);
	
	public enum TipoBD{
		HSQLDB
		,ORACLE;
	}
	
	private static SecuenciasJpaDbpUtils instancia = new SecuenciasJpaDbpUtils();
	/**
	 * Nos devuelve una implementación.
	 * @return
	 */
	public static SecuenciasJpaDbpUtils obtenerInstancia(){
		return instancia;
	}
	
	/**
	 * Nos devuelve el siguiente número de la secuencia que le pasemos.
	 * 
	 * 	
	 * @param entityManager	El entityManager con el que vamos a trabajar.
	 * @param secuencia		La secuencia con la que vamos a trabajar.
	 * @param tipo			El tipo de B.D. con la que vamos a trabajar.
	 * @return
	 */
	public Long obtenerNumeroSecuencia(EntityManager entityManager,String secuencia,TipoBD tipo){
		Long valdev=null;
		switch(tipo){
			case HSQLDB:{
				valdev= obtenerNumeroSecuenciaHSQLDB(entityManager,secuencia);
				break;
			}
			case ORACLE:{
				valdev= obtenerNumeroSecuenciaOracle(entityManager,secuencia);
				break;
			}
		}
		return valdev;
	}
	/**
	 * 
	 * Se encarga de obetener el valor de una secuencia desde JPA, en HSQLDB. 
	 * 		
	 * 		- Para poder usar esta utilidad es necesario ejecutar el siguiente código en tu B.D.
	 * 
	 * CREATE TABLE DUAL (DUMMY VARCHAR(10));
	 *	insert into dual values 1;
	 *  commit;
	 * 
	 * @param entityManager	El entityManager con el que trabajamos.
	 * @param secuencia		El nombre de la secuencia
	 * @return
	 */
	private Long obtenerNumeroSecuenciaHSQLDB(EntityManager entityManager,String secuencia){
		Query q = entityManager.createNativeQuery("SELECT NEXT VALUE FOR "+secuencia+" FROM dual");
		return ((Integer)q.getSingleResult()).longValue();
	}
	/**
	 * 
	 * Se encarga de obtener el valor de una secuenca desde JPA, en ORACLE.
	 * 
	 * @param entityManager	El entityManager con el que trabajamos.
	 * @param secuencia		El nombre de la secuencia
	 * @return
	 */
	
	private Long obtenerNumeroSecuenciaOracle(EntityManager entityManager,String secuencia){
		Query q = entityManager.createNativeQuery("select "+secuencia+".nextval  from dual");
		return ((BigDecimal)q.getSingleResult()).longValue();
	}
}
